#include "pch.h"

D3D11_INPUT_ELEMENT_DESC vertexDeclaration_base[] =
{
	{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
	{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,    0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

const float half_vertex_size = 0.5f;

void RenderDeclaration::Initialize()
{
	//sampler
	{
		D3D11_SAMPLER_DESC samplerDescription;
		ZeroMemory(&samplerDescription, sizeof(D3D11_SAMPLER_DESC));
		samplerDescription.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
		samplerDescription.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDescription.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDescription.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
		samplerDescription.MipLODBias = 0.0f;
		samplerDescription.MaxAnisotropy = DirectX2DRender::Instance()->GetFeatureLevel() > D3D_FEATURE_LEVEL_9_1 ? 4 : 2;
		samplerDescription.ComparisonFunc = D3D11_COMPARISON_NEVER;
		samplerDescription.BorderColor[0] = 0.0f;
		samplerDescription.BorderColor[1] = 0.0f;
		samplerDescription.BorderColor[2] = 0.0f;
		samplerDescription.BorderColor[3] = 0.0f;
		// allow use of all mip levels
		samplerDescription.MinLOD = 0;
		samplerDescription.MaxLOD = D3D11_FLOAT32_MAX;

		DX::ThrowIfFailed(
			DirectX2DRender::Instance()->GetDevice()->CreateSamplerState(
			&samplerDescription,
			&m_sampler_base
			)
			);
	}

	//vertex buffer declaration
	{
		m_init_vertex_Data.SysMemPitch = 0;
		m_init_vertex_Data.SysMemSlicePitch = 0;
		m_subresource_vertex_vector.resize(NUMVERTICES);

		m_subresource_vertex_vector[0].position = DirectX::XMFLOAT3(-half_vertex_size, -half_vertex_size, 0.f);
		m_subresource_vertex_vector[0].textureCoordinate = DirectX::XMFLOAT2(0.f, 0.f);

		m_subresource_vertex_vector[1].position = DirectX::XMFLOAT3(half_vertex_size, -half_vertex_size, 0.f);
		m_subresource_vertex_vector[1].textureCoordinate = DirectX::XMFLOAT2(1.f, 0.f);

		m_subresource_vertex_vector[2].position = DirectX::XMFLOAT3(half_vertex_size, half_vertex_size, 0.f);
		m_subresource_vertex_vector[2].textureCoordinate = DirectX::XMFLOAT2(1.f, 1.f);

		m_subresource_vertex_vector[3].position = DirectX::XMFLOAT3(-half_vertex_size, half_vertex_size, 0.f);
		m_subresource_vertex_vector[3].textureCoordinate = DirectX::XMFLOAT2(0.f, 1.f);

		m_init_vertex_Data.pSysMem = m_subresource_vertex_vector.data();
	}


	//index buffer declaration
	{
		m_init_index_Data.SysMemPitch = 0;
		m_init_index_Data.SysMemSlicePitch = 0;
		m_subresource_index_vector.resize(NUMINDICES);

		m_subresource_index_vector[0] = 3;
		m_subresource_index_vector[1] = 1;
		m_subresource_index_vector[2] = 0;

		m_subresource_index_vector[3] = 3;
		m_subresource_index_vector[4] = 2;
		m_subresource_index_vector[5] = 1;
 
		m_init_index_Data.pSysMem = m_subresource_index_vector.data();
	}

	//create vb&ib
	{
		D3D11_BUFFER_DESC bd = {0};
		{
			bd.Usage = D3D11_USAGE_DEFAULT;
			bd.ByteWidth = sizeof(RectPointVertex) * NUMVERTICES;
			bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
			bd.CPUAccessFlags = 0;

			DX::ThrowIfFailed(
				DirectX2DRender::Instance()->GetDevice()->CreateBuffer(&bd, &RenderDeclaration::Instance()->GetRectVertexDeclData(), &m_spritevertexBuffer)
				);
		}


		{
			bd.Usage = D3D11_USAGE_DEFAULT;
			bd.ByteWidth = sizeof(uint16) * NUMINDICES;
			bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
			bd.CPUAccessFlags = 0;

			DX::ThrowIfFailed(
				DirectX2DRender::Instance()->GetDevice()->CreateBuffer(&bd, &RenderDeclaration::Instance()->GetRectIndexDeclData(), &m_spriteindexBuffer)
				);
		}
	}

	// base vs&ps
	{
		BasicLoader^ loader = ref new BasicLoader(DirectX2DRender::Instance()->GetDevice().Get());

		loader->LoadShader(
			L"SimpleVertexShader.cso",
			vertexDeclaration_base,
			ARRAYSIZE(vertexDeclaration_base),
			&m_vertexShader_base,
			&m_inputLayout_base
			);

		loader->LoadShader(
			L"SimplePixelShader.cso",
			&m_pixelShader_base
			);
	}

	// global constant buffer
	{
		// create the constant buffer for updating model and camera data
		CD3D11_BUFFER_DESC constantBufferDescription(sizeof(GlobalConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
		DX::ThrowIfFailed(
			DirectX2DRender::Instance()->GetDevice()->CreateBuffer(
			&constantBufferDescription,
			nullptr,             // leave the buffer uninitialized
			&m_constantBufferGlobal
			)
			);
	}
}

Microsoft::WRL::ComPtr<ID3D11SamplerState> RenderDeclaration::GetSampler()
{
	return m_sampler_base;
}

Microsoft::WRL::ComPtr<ID3D11InputLayout> RenderDeclaration::GetInputLayout()
{
	return m_inputLayout_base;
}


Microsoft::WRL::ComPtr<ID3D11VertexShader> RenderDeclaration::GetVertexShader()
{
	return m_vertexShader_base;
}

Microsoft::WRL::ComPtr<ID3D11PixelShader> RenderDeclaration::GetPixelShader()
{
	return m_pixelShader_base;
}


Microsoft::WRL::ComPtr<ID3D11Buffer> RenderDeclaration::GetSpriteVertexBuffer()
{
	return m_spritevertexBuffer;
}
	
Microsoft::WRL::ComPtr<ID3D11Buffer> RenderDeclaration::GetSpriteIndexBuffer()
{
	return m_spriteindexBuffer;
}

Microsoft::WRL::ComPtr<ID3D11Buffer> RenderDeclaration::GetConstantBufferGlobal()
{
	return m_constantBufferGlobal;
}

const D3D11_SUBRESOURCE_DATA& RenderDeclaration::GetRectVertexDeclData()
{
	return m_init_vertex_Data;
}

const D3D11_SUBRESOURCE_DATA& RenderDeclaration::GetRectIndexDeclData()
{
	return m_init_index_Data;
}
RenderDeclaration::RenderDeclaration()
{
	
}
